﻿using System;
using System.IO;

namespace TeamsPortal.ServiceClient
{
    public interface IFileStorageService
    {
        /// <summary>
        /// Saves a file stream to file system
        /// </summary>
        /// <param name="file">file stream</param>
        /// <param name="realFileName">file name</param>
        /// <returns>file path in storage</returns>
        string SaveStream(Stream file, string realFileName);

        Stream LoadStream(string p);

        void Remove(string path);
    }

    public class FileStorageService : IFileStorageService
    {
        private readonly string _fileStoragePath;
        private readonly IFileSystemProvider _fileSystemProvider;

        public FileStorageService(string fileStoragePath, IFileSystemProvider fileSystemProvider)
        {
            if (fileStoragePath == null)
                throw new ArgumentNullException("fileStoragePath", "File storage path should not be null");
            if (fileSystemProvider == null)
                throw new ArgumentNullException("fileSystemProvider");

            _fileStoragePath = fileStoragePath + (fileStoragePath.EndsWith("\\") ? "" : "\\");
            _fileSystemProvider = fileSystemProvider;
        }

        public string SaveStream(Stream fileStream, string extension)
        {
            if (fileStream == null)
                throw new ArgumentNullException("fileStream", "File stream is null");
            if (string.IsNullOrEmpty(extension))
                throw new ArgumentException("File extension is not provided");

            string fileGuid = Guid.NewGuid().ToString("D");
            //string fileName = fileGuid  + Path.GetExtension(extension);
            string fileName = Path.ChangeExtension(fileGuid, extension);
            string relativePath = string.Format(@"{0}\{1}\{2}\{3}", 
                fileGuid.Substring(0,1),
                fileGuid.Substring(1,1),
                fileGuid.Substring(2,1),
                fileName);

            var fileBuffer = new byte[fileStream.Length];
            fileStream.Read(fileBuffer, 0, (int)fileStream.Length - 1);
            _fileSystemProvider.WriteAllBytes(_fileStoragePath + relativePath, fileBuffer);

            return relativePath;
        }

        //todo:unit test
        public Stream LoadStream(string path)
        {
            if (string.IsNullOrEmpty(path))
                throw new ArgumentNullException("path", "Path of loaded file must be provided.");

            FileStream stream = _fileSystemProvider.OpenRead(Path.Combine(_fileStoragePath, path));

            return stream;
        }


        public void Remove(string path)
        {
            if (string.IsNullOrEmpty(path))
                throw new ArgumentNullException("path", "Path of loaded file must be provided.");

            _fileSystemProvider.Delete(Path.Combine(_fileStoragePath, path));
        }
    }
}
